//
//  Snake.m
//  DualSnake
//
//  Created by HacJune Lee on 13. 12. 9..
//  Copyright (c) 2013년 HakJune Lee. All rights reserved.
//

#import "Snake.h"
#import "SnakeBody.h"
#import "SnakeHead.h"

@implementation Snake
-(id)init
{
    self = [super init];
    if(self)
    {
        _arr_snakeBlock = [[NSMutableArray alloc]init];
        [self createFristSnake];
        
        _moveTimeInterval = 1.0;
        [self snakeThreadStart];
    }
    return self;
}

-(void)createFristSnake
{
    int gridCount = [[GameMaster shared]getGridCount];
    
    _snakeNextDirection = DIRECTION_TOP;
    
    SnakeHead * header = [[SnakeHead alloc]initWithBlockType:GAMEBLOCK_SNAKE_HEAD];
    header.nextDirection = DIRECTION_RIGHT;
    [header settingWithImage:[UIImage imageNamed:@"Box_Red.png"] gridNum:[[GameMaster shared]getSingleModePlayerStartGridNum]];
    
    [_arr_snakeBlock addObject:header];
    
    SnakeBody * body = [[SnakeBody alloc]initWithBlockType:GAMEBLOCK_SNAKE_BODY];
    [body settingWithImage:[UIImage imageNamed:@"Box_Green.png"] gridNum:(header.gridNum + gridCount)];
    body.nextDirection = _snakeNextDirection;
    
    [_arr_snakeBlock addObject:body];
    
    [self addSnakeBody:2];
}

-(SnakeBody*)createSnakeBodyBlock
{
    SnakeBody * bodyBlock = [[SnakeBody alloc]initWithBlockType:GAMEBLOCK_SNAKE_BODY];
    
    SnakeBody * lastBody = [_arr_snakeBlock lastObject];
    int lastBodyGridNum = lastBody.gridNum;
    int lastBodyNextDirection = lastBody.nextDirection;
    int gridCount = [[GameMaster shared]getGridCount];
    
    int gridNum = -1;
    switch (lastBodyNextDirection) {
        case DIRECTION_TOP:
            gridNum = lastBodyGridNum + gridCount;
            break;
        case DIRECTION_LEFT:
            gridNum = lastBodyGridNum + 1;
            break;
        case DIRECTION_RIGHT:
            gridNum = lastBodyGridNum - 1;
            break;
        case DIRECTION_BOTTON:
            gridNum = lastBodyGridNum - gridCount;
            break;
            
        default:
            NSLog(@"direction warmming!!!! what the... ");
            break;
    }
    
    [bodyBlock settingWithImage:[UIImage imageNamed:@"Box_Green.png"] gridNum:gridNum];
    return bodyBlock;
}



-(void)addSnakeBody:(int)count
{
    
    for (int i = 0; i < count; i++)
    {
        [_arr_snakeBlock addObject:[self createSnakeBodyBlock]];
    }
}

-(void)dropSnakeBodyWithCount:(int)count
{
    int lastIndex = [_arr_snakeBlock count]-1;
    int startIndex = lastIndex - count;
    
    NSLog(@"arr count %d , startCount %d lastCount %d" , [_arr_snakeBlock count], startIndex, lastIndex);
    [_arr_snakeBlock removeObjectsInRange:NSMakeRange(startIndex, lastIndex)];
}

//새로 생성될 뱀몸통이 마지막 몸통 기준 어느방향에 생기나요?
-(int)getNewBodyDirectionWithLastBodyNextDirection:(int)direction
{
    if( direction == DIRECTION_TOP )
    {
        return DIRECTION_BOTTON;
    }
    else if( direction == DIRECTION_LEFT )
    {
        return DIRECTION_RIGHT;
    }
    else if( direction == DIRECTION_RIGHT )
    {
        return DIRECTION_LEFT;
    }
    else if( direction == DIRECTION_BOTTON )
    {
        return DIRECTION_TOP;
    }
    
    NSLog(@"direction warmming!!!! what the... ");
    return -1;
}

-(void)snakeThreadStart
{
    if(_snakeThread == nil)
    {
        _snakeThread = [[NSThread alloc]initWithTarget:self selector:@selector(snakeLoop) object:nil];
    }
    [self performSelector:@selector(tmp) withObject:nil afterDelay:2.0];
}

-(void)tmp
{
    [_snakeThread start];
}

-(void)snakeThreadStop
{
    [_snakeThread cancel];
    _snakeThread = nil;
}

-(void)snakeLoop
{
    while ([_snakeThread isCancelled] == NO)
    {
        [self snakeMove];
        [NSThread sleepForTimeInterval:_moveTimeInterval];
    }
}

-(void)snakeMove
{
    NSLog(@"snakeMove now time interval : %f", _moveTimeInterval);
    
    for (int i = 0; i < [_arr_snakeBlock count]; i++)
    {
        GameBlock * snakeBlock = [_arr_snakeBlock objectAtIndex:i];
        
        //머리일때.
        if([snakeBlock isKindOfClass:[SnakeHead class]])
        {
            snakeBlock.beforeGridNum = snakeBlock.gridNum;
            snakeBlock.gridNum = [self nextSnakeHeadGridNumWithSnakeBlock:snakeBlock];
        }
        //몸통일때.
        else
        {
            
            //NSLog(@"gridNum : %d" , snakeBlock.gridNum);
            snakeBlock.beforeGridNum = snakeBlock.gridNum;
            //NSLog(@"beforeGridNum : %d  , gridNum : %d" , snakeBlock.beforeGridNum ,snakeBlock.gridNum);
            
            GameBlock * beforeSnakeBlock = ((GameBlock *)[_arr_snakeBlock objectAtIndex:(i-1)]);
            snakeBlock.gridNum = beforeSnakeBlock.beforeGridNum;
            //NSLog(@"beforeGridNum : %d  , gridNum : %d" , snakeBlock.beforeGridNum ,snakeBlock.gridNum);
        }
        //NSLog(@"snakeBlock.gridNum : %d" , snakeBlock.gridNum);
        
        [snakeBlock resetDrawPoint];
        //NSLog(@"drawPoint : %@" , NSStringFromCGPoint(snakeBlock.drawPoint));
    }
    
    //스레드에서 빼내야만 리드로우가 동작한다.
    [self performSelectorOnMainThread:@selector(redrawSelectorCall) withObject:nil waitUntilDone:YES];
}

-(void)redrawSelectorCall
{
    //스네이크 본인은 오브젝트 객체일뿐. 뷰로 리드로우를 넘겨야한다.
    [_delegate reDrawCall];
}

-(int)nextSnakeHeadGridNumWithSnakeBlock:(GameBlock*)snakeBlock
{
    int gridCount = [[GameMaster shared] getGridCount];
    int inputDirection = [[GameMaster shared]getInputDirectionWithSnakeTag:0];
    
    if(inputDirection == -1)
    {
        inputDirection = 100;
    }
    
    if( inputDirection == DIRECTION_TOP )
    {
        return snakeBlock.gridNum - gridCount;
    }
    else if( inputDirection == DIRECTION_LEFT )
    {
        return snakeBlock.gridNum - 1;
    }
    else if( inputDirection == DIRECTION_RIGHT )
    {
        return snakeBlock.gridNum + 1;
    }
    else if( inputDirection == DIRECTION_BOTTON )
    {
        return snakeBlock.gridNum + gridCount;
    }
    else
    {
        NSLog(@"warming!!! next grid num -1 !!!");
        return -1;
    }
}




-(void)drawGameblock
{
    SnakeHead * head = [_arr_snakeBlock firstObject];
    [head drawGameblock];
    
    for (int i = 1; i < [_arr_snakeBlock count]; i++)
    {
        SnakeBody * body = [_arr_snakeBlock objectAtIndex:i];
        [body drawGameblock];
    }
}

@end
